;; -*- mode: Lisp; tab-width: 4; -*-


;; =============================================================================
;; global variables related to local file locations
(setq *lisp-and-slime-settings-location* "~/emacs-custom/lisp-and-slime.el")
(setq *linum-location* "~/emacs-custom/lisp-and-slime.el")


;; =============================================================================
;; set default dir
(setq default-directory "~/proj")

;; don't show startup screen anymore
(setq inhibit-startup-message t)

;; follow VC symbolic links without warning
(setq vc-follow-symlinks t)

;; =============================================================================
;; slime: clisp interaction
(load-file *lisp-and-slime-settings-location*)
(require 'slime)
(slime-setup '(slime-scratch slime-editing-commands slime-repl))

;; =============================================================================
;; linum module
(load-file *linum-location*)
(require 'linum)

;; =============================================================================
;; customizing UI
(defun apply-customized-look ()
  "applies customized UI look"
  (interactive)
  ;; hide toolbar
  (tool-bar-mode -1)
  ;; apply custom font face
  (custom-set-faces '(default ((t (:height 90 :family "DejaVu Sans Mono" :embolden t))))))

;; =============================================================================
;; global key bindings

;; Meta
(global-set-key "\M-\C-h" 'backward-kill-word)
(global-set-key "\M-g" 'goto-line)
(global-set-key "\M-r" 'replace-string)

;; Function keys
(global-set-key [f1] 'manual-entry)
(global-set-key [f2] 'buffer-menu)
(global-set-key [f3] 'shell)
(global-set-key [f4] 'grep)
(global-set-key [f5] 'slime)
(global-set-key [f6] 'slime-repl-quit)
(global-set-key [f7] 'other-window)
(global-set-key [f8] 'dired)
(global-set-key [f9] 'switch-to-buffer)
(global-set-key [f10] 'apply-customized-look)


;; =============================================================================
;; mixed indentation
(setq indent-tabs-mode nil)


;; =============================================================================
;; helper function for deleting subsequent whitespaces from cursor position
(defun delete-whitespaces-forward ()
  "deletes all the whitespace characters (space, newline, carriage return, tab)
starting from the cursor's position before the first non-whitespace character"
  (interactive)
  (delete-region (point) (progn (skip-chars-forward " \t\r\n") (point))))


;; =============================================================================
;; provides easy-to-use bookmarking functionality
(defun bind-navigation-commands-to-numkeys ()
  "provides easy-to-use bookmarking functionality - binds navigation commands to
C-{index}, M-{index} keys, where index is a numeric key from 1 to 9,
C-{index} - saves bookmark, M-{index} - jumps to the saved point"
  ;; assign handlers for C/M-[1..9] keys
  (loop for key-index from 1 to 9 do
       (let ((key-str (int-to-string key-index)))
	 ;; save point
	 (local-set-key
	  ;; retrieve C-{index} keyboard sequence
	  (read-kbd-macro (concat "C-" (int-to-string key-index)))
	  ;; handler form
	  `(lambda ()
	     (interactive)
	     (point-to-register ,key-index)
	     (message (concat "setting bookmark #" ,key-str))))
	 
	 ;; goto saved point
	 (local-set-key
	  ;; retrieve M-{index} keyboard sequence
	  (read-kbd-macro (concat "M-" (int-to-string key-index)))
	  ;; handler form
	  `(lambda () (interactive) (register-to-point ,key-index))))))


;; =============================================================================
;; establishes key bindings etc. that is common for all the languages tuned
(defun apply-generic-settings-for-all-langs ()
  "applies generic emacs settings e.g. key bindings"
  (local-set-key "\C-d" 'delete-whitespaces-forward)
  (local-set-key "\C-\M-z" 'apply-customized-look)
  (bind-navigation-commands-to-numkeys)
  
  t)

;; =============================================================================
;; C/C++ mode

(defun apply-settings-for-c-and-c++ ()
  (c-set-style "bsd")
  (apply-generic-settings-for-all-langs)
  (define-key c++-mode-map [return] 'newline-and-indent)
  (setq c-basic-offset 4))

;; indentation style for C++-files
(add-hook 'c++-mode-hook
 '(lambda ()
    (apply-settings-for-c-and-c++)
    ;; custom c++ settings
    (c-set-offset 'innamespace 0) ; no indent after namespace
    (c-set-offset 'inline-open 0) ; no indent after inline functions defined in classes
    ))

(add-hook 'c-mode-hook
 '(lambda ()
    (apply-settings-for-c-and-c++)))

;; =============================================================================
;; lisp mode

;; this applies generic style for all lisps
(defun apply-generic-lisp-settings ()
  (show-paren-mode 1) ; emacs-only, show matching parens
  ;;(paren-set-mode 'sexp) ; xemacs extension, full s-expression shall be highlighted (other option is 'paren)
  ;; return will cause automatic indentation
  (local-set-key [return] 'newline-and-indent)

  ;; set generic settings
  (apply-generic-settings-for-all-langs)

  (local-set-key "\C-b" 'backward-sexp)             ; moves backward by s-exp
  (local-set-key "\C-f" 'forward-sexp)              ; moves forward by s-exp
  (local-set-key (kbd "C-M-<backspace>") 'backward-kill-sexp) ; kill prev s-exp
  (local-set-key "\C-p" 'backward-kill-sexp)
  (local-set-key "\C-\M-u" 'backward-up-list)
  (local-set-key (kbd "C-;") 'comment-region)
  (local-set-key (kbd "C-M-;") 'uncomment-region)
  )

;; clisp mode
(add-hook 'lisp-mode-hook
 '(lambda () (apply-generic-lisp-settings)))

;; emacs lisp mode
(add-hook 'emacs-lisp-mode-hook
 '(lambda () (apply-generic-lisp-settings)))


;; =============================================================================
;; switch off backup files (not sure if it would be useful for you)
(setq make-backup-files nil)


